/*
 * All content copyright http://www.j2eefast.com, unless
 * otherwise indicated. All rights reserved.
 * No deletion without permission
 */
package com.j2eefast.framework.sys.service;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.j2eefast.common.core.base.entity.Ztree;
import com.j2eefast.common.core.constants.ConfigConstant;
import com.j2eefast.common.core.enums.OperationEventType;
import com.j2eefast.common.core.exception.RxcException;
import com.j2eefast.common.core.page.Query;
import com.j2eefast.common.core.utils.PageUtil;
import com.j2eefast.common.core.utils.RedisUtil;
import com.j2eefast.common.core.utils.SpringUtil;
import com.j2eefast.common.core.utils.ToolUtil;
import com.j2eefast.common.event.SysDictEvent;
import com.j2eefast.framework.redis.SysConfigRedis;
import com.j2eefast.framework.sys.entity.SysDictDataEntity;
import com.j2eefast.framework.sys.entity.SysDictTypeEntity;
import com.j2eefast.framework.sys.mapper.SysDictTypeMapper;
import com.j2eefast.framework.utils.Constant;
import com.j2eefast.framework.utils.RedisKeys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * 数据字典Key
 */
@Service
public class SysDictTypeSerive extends ServiceImpl<SysDictTypeMapper,SysDictTypeEntity> {

    @Autowired
    private SysDictDataService sysDictDataService;
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SysConfigRedis sysConfigRedis;

    /**
     * 页面展示查询翻页
     */
    public PageUtil findPage(Map<String, Object> params) {
        String dictName = (String) params.get("dictName");
        String appName = (String) params.get("appName");
        String appNo = (String) params.get("appNo");
        String dictType = (String) params.get("dictType");
        String status = (String) params.get("status");
        LambdaQueryWrapper<SysDictTypeEntity> gw = SysDictTypeEntity.gw();
        gw.like(ToolUtil.isNotEmpty(appName),SysDictTypeEntity::getAppName,appName);
        gw.like(ToolUtil.isNotEmpty(dictName),SysDictTypeEntity::getDictName,dictName);
        gw.like(ToolUtil.isNotEmpty(appNo),SysDictTypeEntity::getAppNo,appNo);
        gw.eq(ToolUtil.isNotEmpty(status),SysDictTypeEntity::getStatus,status);
        gw.like(ToolUtil.isNotEmpty(dictType),SysDictTypeEntity::getDictType,dictType);
        Page<SysDictTypeEntity> page = this.baseMapper.selectPage(new Query<SysDictTypeEntity>(params).getPage(),
                gw);
        return new PageUtil(page);
    }


    public boolean checkDictTypeUnique(SysDictTypeEntity dict) {
        Long dictId = ToolUtil.isEmpty(dict.getId()) ? -1L : dict.getId();
        SysDictTypeEntity dictType = this.getOne(SysDictTypeEntity.gw()
                .eq(SysDictTypeEntity::getDictType,dict.getDictType())
                .eq(SysDictTypeEntity::getAppNo,dict.getAppNo()));
        if (!ToolUtil.isEmpty(dictType) &&
                !dictType.getId().equals(dictId)){
            return  false;
        }
        return true;
    }


    public List<Ztree> dictTypeTreeData() {
        List<SysDictTypeEntity> dictList = this.list();
        List<Ztree> ztrees = new ArrayList<Ztree>();
        for (SysDictTypeEntity dict : dictList){
            if ("0".equals(dict.getStatus())){
                Ztree ztree = new Ztree();
                ztree.setId(String.valueOf(dict.getId()));
                ztree.setTitle(transDictName(dict));
                ztree.setName(dict.getDictType());
                ztrees.add(ztree);
            }
        }
        return ztrees;
    }

    public String transDictName(SysDictTypeEntity dictType){
        StringBuffer sb = new StringBuffer();
        sb.append("(" + dictType.getDictName() + ")");
        sb.append("&nbsp;&nbsp;&nbsp;" + dictType.getDictType());
        return sb.toString();
    }

    @Transactional(rollbackFor = Exception.class)
    public boolean deleteBatchByIds(Long[] ids) {
        List<SysDictTypeEntity> dictList = new ArrayList<>();
        for (Long dictId : ids){
            SysDictTypeEntity dictType = this.getById(dictId);
            if (!ToolUtil.isEmpty(dictType) &&
                    sysDictDataService.countDictDataByType(dictType.getDictType(),dictType.getAppNo()) > 0){
                throw new RxcException(String.format("%1$s已分配,不能删除", dictType.getDictName()),"50001");
            }
            dictList.add(dictType);
       }
       if(this.removeByIds(Arrays.asList(ids))){
           Optional.ofNullable(dictList).ifPresent(t->{
               t.forEach(e->{
                   SysDictEvent event  = new SysDictEvent(e);
                   event.setAppNo(e.getAppNo());
                   event.setDictType(e.getDictType());
                   event.setOperationEventType(OperationEventType.DEL);
                   SpringUtil.publishEvent(event);
               });
           });
           return true;
       }
       return false;
    }

    /**
     * 修改字典Type信息
     * @param dict
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public boolean updateDictType(SysDictTypeEntity dict){
        SysDictTypeEntity sysDictType = this.getById(dict.getId());
        if(!sysDictType.getDictType().equals(dict.getDictType())){
            //修改关联信息
            sysDictDataService.update(new LambdaUpdateWrapper<SysDictDataEntity>()
                    .eq(SysDictDataEntity::getDictType,sysDictType.getDictType())
                    .eq(SysDictDataEntity::getAppNo,sysDictType.getAppNo())
                    .set(SysDictDataEntity::getDictType,dict.getDictType()));
            sysConfigRedis.delRedisDict(sysDictType.getDictType());
        }
        if(this.updateById(dict)){
            SysDictEvent event  = new SysDictEvent(dict);
            event.setAppNo(dict.getAppNo());
            event.setDictType(dict.getDictType());
            event.setOperationEventType(OperationEventType.UPDATE);
            SpringUtil.publishEvent(event);
            return true;
        }
        return false;
    }


    public boolean clearDictRedis(){
        ConfigConstant.DICT_TAG = RandomUtil.randomString(5);
        SysDictEvent event  = new SysDictEvent();
        event.setOperationEventType(OperationEventType.CLEAR);
        SpringUtil.publishEvent(event);
        Constant.SYS_DICT.clear();
        return redisUtil.deletes(RedisKeys.getDictConfigKey("*"));
    }

}
